package com.free.utils.crypt;

import com.free.exception.SystemRuntimeException;
import com.free.utils.CharsetUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class TripleDESCrypt
{
    private static final String ALGORITHM = "DESede";
    private static final int KEY_LEN = 24;

    private static final Cipher cipher;

    static
    {
        try
        {
            cipher = Cipher.getInstance(ALGORITHM);
        }
        catch (NoSuchAlgorithmException | NoSuchPaddingException e)
        {
            throw new SystemRuntimeException("解密出错", e);
        }
    }

    public static String encrypt(String src, String key)
    {
        try
        {
            SecretKey skey = new SecretKeySpec(createKey(key), ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            return Base64.encodeBase64String(cipher.doFinal(src.getBytes(CharsetUtils.UTF8_CHARSET)));
        }
        catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
        {
            throw new SystemRuntimeException("解密出错", e);
        }
    }

    public static String decrypt(String src, String key)
    {
        try
        {
            SecretKey skey = new SecretKeySpec(createKey(key), ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, skey);
            return new String(cipher.doFinal(Base64.decodeBase64(src)), CharsetUtils.UTF8_CHARSET);
        }
        catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
        {
            throw new SystemRuntimeException("解密出错", e);
        }
    }

    private static byte[] createKey(String key)
    {
        byte[] newKey = SHACrypt.sha256(key);
        return ArrayUtils.subarray(newKey, 0, KEY_LEN);
    }

    // TEST
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        String key = "abcdefg12345";
        String t = "abcde";
        String s = TripleDESCrypt.encrypt(t, key);
        String o = TripleDESCrypt.decrypt(s, key);
        System.out.println(t);
        System.out.println(s);
        System.out.println(o);

        String p = BCrypt.hashpw(t);
        System.out.println(p);
        System.out.println(BCrypt.checkpw(t, p));

        p = BCrypt.hashpw(t);
        System.out.println(p);
        System.out.println(BCrypt.checkpw(t, p));
    }
}
